package io.tim.webserver.simple01;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;

/**
 * 
 * 通过 ServerSocket 实现的简单 http server 处理线程
 * @author Zhang Nan
 * @since	[Date: 2/27/2017]
 *
 */
public class Processor implements Runnable {
	
	private Socket socket;
	private InputStream in;
	private PrintStream out;
	private final static String WEB_ROOT = "D:\\资料\\Spring Solutions\\spring-tool-suite-3.8.1.RELEASE-e4.6-win32-x86_64\\sts-bundle\\sts-3.8.1.RELEASE\\workspace\\architect\\Apache_1\\html\\";
	private final static String HTTP_VERSION_01 = "HTTP/1.0";
	
	public Processor(Socket socket) {
		this.socket = socket;
		try {
			in = socket.getInputStream();
			out = new PrintStream(socket.getOutputStream());
		} catch (IOException e) {
			e.printStackTrace();
		}
		run();
	}

	@Override
	public void run() {
		
		// 首先解析输入流，获得申请访问的文件名，比如某个 html 文件
		String fileName = parse(in);
		sendFile(fileName);
		try {
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 解析输入流的内容为文本
	public String parse(InputStream in) {
		String fileName = "";
		BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(in));
		
		try {
			String httpMessage = bufferedReader.readLine();
			/*
			 * 首先获取从客户端发到服务器端的请求的第一行，应该是一个包含三个字符串元素的数组
			 * 即：“方法、URI协议、版本”，例如：GET/sample.jsp HTTP/1.1
			 * 
			*/
			String [] content = httpMessage.split(" ");
			
			// 如果请求信息的分割长度不是 3，则说明请求内容有错误，返回 400 错误
			if (content.length != 3) {
				String errorCode = WrapperEnumInfo.REQUEST_ERROR.getCode();
				String errorMessage = WrapperEnumInfo.REQUEST_ERROR.getMessage();
				sendErrorMessage(errorCode, errorMessage);
			}
			System.out.println("method: " + content[0] + ", fileName: " + content[1] + ", http version: " + content[2]);
			fileName = content[1];
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return fileName;
	}
	
	// 返回错误信息
	public void sendErrorMessage(String errorCode, String errorMessage) {
		
		out.println(Processor.HTTP_VERSION_01 + " " + errorCode + " " + errorMessage);
		out.println("content-type: text/html");
		out.println();
		out.println("<html>");
		out.println("<title> Error Message ");
		out.println("</title>");
		out.println("<body>");
		out.println("<h1> ErrorCode: " + errorCode + ", ErrorMessage: " + errorMessage + "</h1>");
		out.println("</body>");
		out.println("</html>");
		out.flush();
		out.close();
		try {
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	// 返回客户端申请的资源
	public void sendFile(String fileName) {
		
		// 根据文件名在服务器上的 Web 服务根目录下找到该文件
		File file = new File(Processor.WEB_ROOT + fileName);
		
		// 如果该文件不存在，则返回 404 错误
		if (!file.exists()) {
			String errorCode = WrapperEnumInfo.FILE_NOT_FOUND.getCode();
			String errorMessage = WrapperEnumInfo.FILE_NOT_FOUND.getMessage();
			sendErrorMessage(errorCode, errorMessage);
			return ;
		}
		
		try {
			// 将文件中的内容读取出来，再通过 PrintStream 返回给客户端
			InputStream in = new FileInputStream(file);
			byte [] fileContent = new byte[(int)file.length()];
			in.read(fileContent);
			
			// 1. 返回协议的版本号、状态码和解释信息
			out.println(Processor.HTTP_VERSION_01 + " " + WrapperEnumInfo.REQUEST_SUCCESS.getCode() + " " + "query file");
			// 2. 返回文件长度
			out.println("content-length: " + fileContent.length);
			// 3. 空行后返回文件内容
			out.println();
			out.write(fileContent);
			// 4. 关闭输入输出
			out.flush();
			out.close();
			in.close();
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
}
